package abiz

import (
	"encoding/json"
	"fmt"
	"time"
	"xin-job/core/biz"
	"xin-job/core/httpclient"
)

var i = &ExecutorBizClient{}

func GetExecutorBizClient() *ExecutorBizClient {
	return i
}

type ExecutorBizClient struct {
	Httpclient       httpclient.Httpclient
	ClientAddressUrl string
	AccessToken      string
	Timeout          time.Duration
}

func (c *ExecutorBizClient) Beat() biz.Return[string] {
	var url = c.ClientAddressUrl + "beat"
	return c.exec(url, nil)
}

func (c *ExecutorBizClient) IdleBeat(idleBeatParam *biz.IdleBeatParam) biz.Return[string] {
	var url = c.ClientAddressUrl + "idleBeat"
	return c.exec(url, idleBeatParam)
}
func (c *ExecutorBizClient) Run(triggerParam *biz.TriggerParam) biz.Return[string] {
	var url = c.ClientAddressUrl + "run"
	return c.exec(url, triggerParam)
}
func (c *ExecutorBizClient) Kill(killParam *biz.KillParam) biz.Return[string] {
	var url = c.ClientAddressUrl + "kill"
	return c.exec(url, killParam)
}
func (c *ExecutorBizClient) Log(logParam *biz.LogParam) biz.Return[biz.LogResult] {
	var url = c.ClientAddressUrl + "log"
	body, err := json.Marshal(logParam)
	if err != nil {
		return biz.Return[biz.LogResult]{
			Code: 500,
			Msg:  fmt.Sprintf("json marshal err:%s", err.Error()),
		}
	}

	resp, err := c.Httpclient.Url(url).Body(body).Post()
	if err != nil {
		return biz.Return[biz.LogResult]{
			Code: 500,
			Msg:  fmt.Sprintf("send http post err:%s", err.Error()),
		}
	}

	if resp.StatusCode != 200 {
		return biz.Return[biz.LogResult]{
			Code: resp.StatusCode,
			Msg:  fmt.Sprintf("xxl-job remoting fail, StatusCode(%d) invalid. for url : %s", resp.StatusCode, url),
		}
	}

	var r biz.Return[biz.LogResult]
	err = json.Unmarshal(resp.Content, &r)
	if err != nil {
		return biz.Return[biz.LogResult]{
			Code: resp.StatusCode,
			Msg:  fmt.Sprintf("xxl-job json Unmarshal fail, content(%s) invalid. for url : %s", string(resp.Content), url),
		}
	}
	return r

}

func (c *ExecutorBizClient) exec(url string, param any) biz.Return[string] {
	cc := c.Httpclient.Url(url)
	if param != nil {
		body, err := json.Marshal(param)
		if err != nil {
			return biz.Return[string]{
				Code: 500,
				Msg:  fmt.Sprintf("json marshal err:%s", err.Error()),
			}
		}
		cc = cc.Body(body)
	}

	resp, err := cc.Post()
	if err != nil {
		return biz.Return[string]{
			Code: 500,
			Msg:  fmt.Sprintf("send http post err:%s", err.Error()),
		}
	}

	if resp.StatusCode != 200 {
		return biz.Return[string]{
			Code: resp.StatusCode,
			Msg:  fmt.Sprintf("xxl-job remoting fail, StatusCode(%d) invalid. for url : %s", resp.StatusCode, url),
		}
	}

	var r biz.Return[string]
	err = json.Unmarshal(resp.Content, &r)
	if err != nil {
		return biz.Return[string]{
			Code: resp.StatusCode,
			Msg:  fmt.Sprintf("xxl-job json Unmarshal fail, content(%s) invalid. for url : %s", string(resp.Content), url),
		}
	}
	return r
}
